package com.boot.unity.api.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

@Slf4j
@Configuration
public class MyBatisConfig {
    @Value("${mybatisConfig.type-aliases-package}")
    private String typeAliasesPackage;
    @Value("${mybatisConfig.mapper-locations}")
    private String mapperLocations;
    @Value("${mybatisConfig.configuration.mapUnderscoreToCamelCase}")
    private boolean mapUnderscoreToCamelCase;

//    @Autowired
//    private Environment env;

    static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

    public static String setTypeAliasesPackage(String typeAliasesPackage) {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
        typeAliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                + ClassUtils.convertClassNameToResourcePath(typeAliasesPackage)
                + "/" + DEFAULT_RESOURCE_PATTERN;
        try {
            List<String> result = new ArrayList<>();
            Resource[] resources = resolver.getResources(typeAliasesPackage);
            if (resources != null && resources.length > 0) {
                MetadataReader metadataReader;
                for (Resource resource : resources) {
                    if (resource.isReadable()) {
                        metadataReader = metadataReaderFactory.getMetadataReader(resource);
                        try {
                            // System.out.println(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
                            result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            if (result.size() > 0) {
                HashSet<String> h = new HashSet<>(result);
                result.clear();
                result.addAll(h);
                typeAliasesPackage=String.join(",",(String[]) result.toArray(new String[0]));
                log.info(typeAliasesPackage);
            } else {
                log.error("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:[{}]未找到任何包",typeAliasesPackage);
                //throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return typeAliasesPackage;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        //DefaultVFS在获取jar上存在问题，使用springboot只能修改
        //VFS.addImplClass(SpringBootVFS.class);
        log.info("配置的typeAliasesPackage路径: {}",typeAliasesPackage);
        log.info("配置的mapperLocations路径: {}",mapperLocations);
        log.info(">>>>>>>>>>>配置[typeAliasesPackage,mapperLocations]START>>>>>>>>>>>>>>");
        //String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        //String mapperLocations = env.getProperty("mybatis.mapperLocations");
        typeAliasesPackage=setTypeAliasesPackage(typeAliasesPackage);

        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(mapUnderscoreToCamelCase);
        // 同VFS.addImplClass(SpringBootVFS.class);
        configuration.setVfsImpl(SpringBootVFS.class);
        sessionFactory.setConfiguration(configuration);
        log.info(">>>>>>>>>>>配置[typeAliasesPackage,mapperLocations]END>>>>>>>>>>>>>>");
        return sessionFactory.getObject();
    }


    private static void main(String[] args) throws Exception {
        setTypeAliasesPackage("com.boot.unity.api.modules.**.entity");
    }
}